package com.lagou.filter;

import com.lagou.bean.MethodInfo;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Activate(group = {CommonConstants.CONSUMER})
public class TPMonitorFilter implements Filter,Runnable {

    Map<String,List<MethodInfo>> methodTimes = new ConcurrentHashMap<>();

    public TPMonitorFilter(){
        Executors.newSingleThreadScheduledExecutor()
        .scheduleWithFixedDelay(this,5,5,TimeUnit.SECONDS);
        Executors.newSingleThreadScheduledExecutor()
                .scheduleWithFixedDelay(new Thread(new RemoveDataThread(methodTimes)),10,60,TimeUnit.SECONDS);
    }


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Result result = null;
        Long takeTime = 0L;

       try{
           Long startTime = System.currentTimeMillis();
           result = invoker.invoke(invocation);
           if(result.getException() instanceof Exception){
               throw new Exception(result.getException());
           }
           takeTime = System.currentTimeMillis() - startTime;
       } catch (Exception e) {
           e.printStackTrace();
           return result;
       }

        String methodName = invocation.getMethodName();
        List<MethodInfo> methodInfos = methodTimes.get(methodName);
        if(methodInfos == null){
            methodInfos = new ArrayList<>();
            methodTimes.put(methodName,methodInfos);
        }
        methodInfos.add(new MethodInfo(invocation.getMethodName(),takeTime,System.currentTimeMillis()));
        return result;
    }

    private long getIP(List<MethodInfo> methodInfos,double rate){
        List<MethodInfo> sortInfo = new ArrayList<>();

        long endTime = System.currentTimeMillis();
        long startTime = System.currentTimeMillis() - 60000;

        //遍历列表集合
        int length = methodInfos.size();
        for(int i = 0; i<length; i++){
            MethodInfo methodInfo = methodInfos.get(i);
            if(methodInfo.getEndTimes() > startTime && methodInfo.getEndTimes() <endTime){
                sortInfo.add(methodInfo);
            }
        }
        sortInfo.sort(new Comparator<MethodInfo>() {
            @Override
            public int compare(MethodInfo o1, MethodInfo o2) {
                if(o1.getTimes() > o2.getTimes()){
                    return 1;
                }else if(o1.getTimes() < o2.getTimes()){
                    return -1;
                }else {
                    return 0;
                }
            }
        });

        int index =(int)(sortInfo.size()*rate);
        return sortInfo.get(index).getTimes();

    }

    @Override
    public void run() {

    }
}
